<?php

declare(strict_types=1);

namespace Plugin\Attractions\AttractionManagement\Repository;

use App\Repository\IRepository;
use Hyperf\Collection\Arr;
use Hyperf\Collection\Collection;
use Hyperf\Database\Model\Builder;
use Plugin\Attractions\AttractionManagement\Model\AttractionInfo;

class AttractionInfoRepository extends IRepository
{
    public function __construct(protected readonly AttractionInfo $model) {}

    public function handleSearch(Builder $query, array $params): Builder
    {
        return $query
            ->when(Arr::get($params, 'id'), static function (Builder $query, $id) {
                $query->whereIn('id', Arr::wrap($id));
            })
            ->when(Arr::get($params, 'title'), static function (Builder $query, $title) {
                $query->where('title', 'like', '%' . $title . '%');
            })
            ->when(Arr::get($params, 'group'), static function (Builder $query, $group) {
                $query->where('group', $group);
            })
            ->when(Arr::get($params, 'typeId'), static function (Builder $query, $type_id) {
                $query->whereIn('type_id', Arr::wrap($type_id));
            })
            ->when(Arr::get($params, 'spotId'), static function (Builder $query, $spot_id) {
                $query->whereIn('spot_id', Arr::wrap($spot_id));
            })
            ->when(Arr::get($params, 'status'), static function (Builder $query, $status) {
                $query->where('status', $status);
            })
            ->when(Arr::get($params, 'sort'), static function (Builder $query, $sort) {
                $query->orderBy('sort', $sort == 1 ? 'asc' : 'desc');
            });
    }

    public function list(array $params = []): Collection
    {
        return $this->perQuery($this->getQuery(), $params)
            ->with(['type', 'spot', 'tags'])->get(['id', 'title', 'intro', 'group', 'type_id as type', 'spot_id as spot', 'cover_id as coverId', 'status', 'start_time as startTime', 'end_time as endTime']);
    }

    public function showListPage(array $params): array
    { 
        $page = intval(Arr::get($params, 'page', 1));
        $pageSize = intval(Arr::get($params, 'pageSize', 20));
        return $this->perQuery($this->getQuery(), $params)
            ->with(['type:id,name', 'tags'])
            ->simplePaginate($pageSize, ['id', 'title', 'group', 'type_id as typeId', 'spot_id as spotId', 'cover_id as coverId', 'status', 'start_time as startTime', 'end_time as endTime'], 'page', $page)
            ->items();
    }

    public function isValidInfo(array $params): array
    {
        $page = Arr::get($params, 'page', 1);
        $pageSize = Arr::get($params, 'pageSize', 20);
        $isValid = Arr::get($params, 'isValid', 1);
        $query = $this->perQuery($this->getQuery(), $params)
            ->with(['type:id,name', 'tags']);
        if ($isValid == 1) {
            $query = $query->where(function (Builder $query) {
                $query->where('status', 1)
                    ->orWhere(function (Builder $query) {
                        $query->where('status', 3)
                            ->where(function (Builder $query) {
                                $query->where('start_time', '<=', date('Y-m-d H:i:s'))
                                    ->where('end_time', '>', date('Y-m-d H:i:s'));
                            });
                    });
            });
        } else {
            $query = $query->where(function (Builder $query) {
                $query->where('status', 2)
                    ->orWhere(function (Builder $query) {
                        $query->where('status', 3)
                            ->where('start_time', '>', date('Y-m-d H:i:s'))
                            ->orWhere('end_time', '<=', date('Y-m-d H:i:s'));
                    });
            });
        }
        return $query->simplePaginate($pageSize, [
            'id', 'title', 
            'group', 'type_id as typeId', 'spot_id as spotId', 'cover_id as coverId', 
            'status', 'start_time as startTime', 'end_time as endTime'
        ], 'page', $page)->items();
    }

    public function getDetail(int $id)
    {
        return $this->getQuery()->where('id', $id)
            ->with(['type:id,name', 'tags'])
            ->firstOrFail(['id', 'title', 'intro', 'group', 'type_id as typeId', 'spot_id as spotId', 'cover_id as coverId', 'status', 'start_time as startTime', 'end_time as endTime', 'extension'])
            ->toArray();
    }

    public function isValid(int $id)
    {
        return $this->getQuery()->where('id', $id)
            ->where(function (Builder $query) {
                $query->where('status', 1)
                    ->orWhere(function (Builder $query) {
                        $query->where('status', 3)
                            ->where(function (Builder $query) {
                                $query->where('start_time', '<=', date('Y-m-d H:i:s'))
                                    ->where('end_time', '>', date('Y-m-d H:i:s'));
                            });
                    });
            })
            ->exists();
    }

    public function handleOrderBy(Builder $query, $params): Builder
    {
        return $query;
    }
}
